/**
 * 
 * @Project le cOeur - Data Virtualization
 * @Date 08.12.2012
 * @Author Aebi Pascal, Kocher Marc
 * @School BFH-TI Biel, Bachelor Thesis
 *
 */

package main.framework.http;

import java.util.ArrayList;
import java.util.List;

/**
 * This class represents a component defined by the HTTP protocol (RFC-2616).
 */
public class MessageHeaderElement implements Processable {

	protected String headerElement;
	protected String name;
	protected String value;
	protected List<MessageHeaderElementParameter> parameters;
	
	/**
	 * Creates a message header element.
	 * The created message header element needs to be parsed before the object can be used.
	 * 
	 * @param headerElement The message header element string containing a field name, a field value (can be empty) and parameters.
	 */
	public MessageHeaderElement(String headerElement) {
		this.parameters = new ArrayList<>();
		this.headerElement = headerElement;
	}
	
	/**
	 * Creates a message header element.
	 * 
	 * @param name The field name.
	 * @param value The field value.
	 * @param parameters The parameters.
	 */
	public MessageHeaderElement(String name, String value, List<MessageHeaderElementParameter> parameters) {
		this.name = name;
		this.value = value;
		this.parameters = parameters;
	}

	@Override
	public void parse() {
		this.parseElement();
		for (MessageHeaderElementParameter parameter : this.parameters) {
			parameter.parse();
		}
	}

	@Override
	public String compose() {
		StringBuilder stringBuilder = new StringBuilder();
		// Compose element
		stringBuilder.append(this.composeElement());
		// Compose parameters
		if(this.parameters != null){
			for (MessageHeaderElementParameter parameter : this.parameters) {
				stringBuilder.append(";");
				stringBuilder.append(parameter.toString());
			}
		}
		return stringBuilder.toString();
	}
	
	@Override
	public String toString() {
		return this.compose();
	}
	
	/**
	 * Returns the field name of the message header element.
	 * 
	 * @return The field name.
	 */
	public String getName() {
		return this.name;
	}
	
	/**
	 * Returns the field value of the message header element.
	 * 
	 * @return The field value.
	 */
	public String getValue() {
		return this.value;
	}
	
	/**
	 * Returns a list containing all message header element parameters.
	 * 
	 * @return The message header element parameters.
	 */
	public List<MessageHeaderElementParameter> getParameters() {
		return this.parameters;
	}

	/**
	 * Returns the message header element parameter of the given index.
	 * 
	 * @param index The index of the parameter list.
	 * @return The message header element parameter.
	 */
	public MessageHeaderElementParameter getParameter(int index) {
		return this.parameters.get(index);
	}
	
	/**
	 * Parses the message header element.
	 * It sets the different class variables, creates the message header element parameters and adds them to the parameter list.
	 */
	private void parseElement() {
		String[] parameters = this.headerElement.split("\\s*;\\s*");
		String[] element;
		for (int i = 0; i < parameters.length; i++) {
			if(i == 0){
				element = parameters[i].split("\\s*=\\s*");
				this.name = element[0];
				if(element.length == 2){
					this.value = element[1];
				}
			}
			else{
				this.parameters.add(new MessageHeaderElementParameter(parameters[i]));
			}
		}
	}
	
	/**
	 * Composes the field name and the field value of the message header element.
	 * 
	 * @return The composed string.
	 */
	private String composeElement() {
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.append(this.name);
		if(this.value != null){
			if(!this.value.isEmpty()){
				stringBuilder.append("=");
				stringBuilder.append(this.value);
			}
		}
		return stringBuilder.toString();
	}

}
